/*
 * @Author: 杰编程 2306248989@qq.com
 * @Date: 2023-08-04 22:52:49
 * @LastEditors: 杰编程 2306248989@qq.com
 * @LastEditTime: 2023-08-04 22:56:30
 * @FilePath: /lesson24/udp/udp_client.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "udp_client.hpp"
#include "errno.hpp"
#include<pthread.h>


void* recv(void*args)
{
    pthread_detach(pthread_self());
    
    int sock=*static_cast<int*>(args);
    while (true)
    {        
        // 2. 接受数据
        char buffer[1024] = {0};
        struct sockaddr_in tmp;
        memset(&tmp, 0, sizeof(tmp));
        socklen_t addrlen = sizeof(tmp); // 这里一定要写清楚，未来你传入的缓冲区大小
        ssize_t n = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, reinterpret_cast<struct sockaddr *>(&tmp), &addrlen);
        if (n > 0)
        {
            buffer[n] = 0;
            std::cout << "client get message# " << buffer << std::endl;
        }
    }
    
}


void Usage(std::string proc)
{
    std::cout << "UsePage:\n\t" << proc << " serverip serverport\n"
              << std::endl;
}

//./clinet serverip serverport
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(USE_ERR);
    }

    // 将server相关数据进行转化,明确server是谁
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(atoi(argv[2]));
    server.sin_addr.s_addr = inet_addr(argv[1]);

    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0)
    {
        perror("sock create error: ");
        exit(SOCKET_ERR);
    }
    std::cout << "clinet create sock successful:" << sock << std::endl;

    pthread_t tid;
    pthread_create(&tid,nullptr,recv,&sock);

    while (true)
    {
        // 1. 输入和发送数据
        // 1.1 输入数据
        std::cerr << "Please Enter#";
        std::string message;
        std::getline(std::cin,message);
        // 1.2 发送数据
        int ret = sendto(sock, message.c_str(), message.size(), 0, reinterpret_cast<struct sockaddr *>(&server), sizeof(server));
        assert(ret != -1);
        (void)ret;
    }

    return 0;
}
